/******************************************************************************/
/* File: message.cpp                                                          */
/******************************************************************************/

#include "message.h"

/******************************************************************************/
/*
 class RegisterRequest
 */
/******************************************************************************/
cJSON * RegisterRequest::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddIntToObject(j, "ToRegister", iToRegister);
        cJSON_AddIntToObject(j, "ServerProtocol", iServProto);
        cJSON_AddStringToObject(j, "ServerIP", sServIP);
        cJSON_AddIntToObject(j, "ServerPort", iServPort);
    }

    return j;
}
    
void RegisterRequest::ParseFromJson(cJSON *json){
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "ToRegister")) != NULL)
        iToRegister = pj->valueint;
        
    if ((pj = cJSON_GetObjectItem(json, "ServerProtocol")) != NULL)
        iServProto = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "ServerIP")) != NULL)
        sServIP = strdup(pj->valuestring);
    
    if ((pj = cJSON_GetObjectItem(json, "ServerPort")) != NULL)
        iServPort = pj->valueint;
}

/******************************************************************************/
/*
 class FlowRequest
 */
/******************************************************************************/

cJSON * FlowRequest::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddIntToObject(j, "FlowHandleType", iHandleType);
        cJSON *json = pfc->GenToJson();
        cJSON_AddItemToObject(j, "FlowConfig", json);
    }

    return j;
}

void FlowRequest::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "FlowHandleType")) != NULL)
        iHandleType = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "FlowConfig")) != NULL) {
        pfc = new FlowConfig();
        pfc->ParseFromJson(pj);
    }

}

/******************************************************************************/
/*
 class Request
 */
/******************************************************************************/

cJSON * Request::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
            
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddIntToObject(j, "RequestType", iRequestType);
        cJSON *json;
        switch(iRequestType) {
            case (1):
                json = pServerReg->GenToJson();
                cJSON_AddItemToObject(j, "ServerRegisterRequest", json);
                break;
            case (2):
                json = pFlowHandle->GenToJson();
                cJSON_AddItemToObject(j, "FlowHandleRequest", json);
                break;
        }
    }

    return j;
}

void Request::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "RequestType")) != NULL)
        iRequestType = pj->valueint;
        
    switch(iRequestType) {
        case (1):
            if ((pj = cJSON_GetObjectItem(json, "ServerRegisterRequest")) != NULL) {
                pServerReg = new RegisterRequest();
                pServerReg->ParseFromJson(pj);
            }
            break;
        case (2):
            if ((pj = cJSON_GetObjectItem(json, "FlowHandleRequest")) != NULL) {
                pFlowHandle = new FlowRequest();
                pFlowHandle->ParseFromJson(pj);
            }
            break;
    }
    
}

/******************************************************************************/
/*
 class FlowReply
 */
/******************************************************************************/

cJSON* FlowReply::GenToJson() {
    cJSON *j = cJSON_CreateObject();
            
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddStringToObject(j, "SenderIP", sSenderIP);
        cJSON_AddStringToObject(j, "RecverIP", sRecverIP);
        cJSON_AddIntToObject(j, "SenderPort", iSenderPort);
        cJSON_AddIntToObject(j, "RecverPort", iRecverPort);
        cJSON *json = pfc->GenToJson();
        cJSON_AddItemToObject(j, "FlowConfig", json);
    }
    
    return j;
}

void FlowReply::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "SenderIP")) != NULL)
        sSenderIP = strdup(pj->valuestring);

    if ((pj = cJSON_GetObjectItem(json, "SenderPort")) != NULL)
        iSenderPort = pj->valueint;

    if ((pj = cJSON_GetObjectItem(json, "RecverIP")) != NULL)
        sRecverIP = strdup(pj->valuestring);

    if ((pj = cJSON_GetObjectItem(json, "RecverPort")) != NULL)
        iRecverPort = pj->valueint;

    if ((pj = cJSON_GetObjectItem(json, "FlowConfig")) != NULL) {
        FlowConfig *pfc = new FlowConfig();
        pfc->ParseFromJson(pj);
    }
}

/******************************************************************************/
/*
 class Reply
 */
/******************************************************************************/

cJSON * Reply::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddIntToObject(j, "ReplyType", iReplyType);
        cJSON_AddIntToObject(j, "Success", iSuccess);
        if (iReplyType == 2) {
            cJSON *json = pFlowReply->GenToJson();
            cJSON_AddItemToObject(j, "FlowReply", json);
        }
    }

    return j;
}

void Reply::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "ReplyType")) != NULL)
        iReplyType = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "Success")) != NULL)
        iSuccess = pj->valueint;
    
    if (iReplyType == 2) {
        if ((pj = cJSON_GetObjectItem(json, "FlowReply")) != NULL) {
            pFlowReply = new FlowReply();
            pFlowReply->ParseFromJson(pj);
        }
    }
}

/******************************************************************************/
/*
 class TcpReport
 */
/******************************************************************************/

cJSON * TcpReport::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();

    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddFloatToObject(j, "BeginTime", fBeginTime);
        cJSON_AddFloatToObject(j, "EndTime", fEndTime);
        cJSON_AddFloatToObject(j, "Interval", fInterval);
        cJSON_AddIntToObject(j, "TransferBytes", iTransfer);
        cJSON_AddFloatToObject(j, "Bandwidth", fBandwidth);
    }

    return j;
}

void TcpReport::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "BeginTime")) != NULL)
        fBeginTime = pj->valuefloat;
    
    if ((pj = cJSON_GetObjectItem(json, "EndTime")) != NULL)
        fEndTime = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "Interval")) != NULL)
        fInterval = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "TransferBytes")) != NULL)
        iTransfer = pj->valueint;
        
    if ((pj = cJSON_GetObjectItem(json, "Bandwidth")) != NULL)
        fBandwidth = pj->valuefloat;
}

/******************************************************************************/
/*
 class UdpReport
 */
/******************************************************************************/

cJSON * UdpReport::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddFloatToObject(j, "BeginTime", fBeginTime);
        cJSON_AddFloatToObject(j, "EndTime", fEndTime);
        cJSON_AddFloatToObject(j, "Interval", fInterval);
        cJSON_AddIntToObject(j, "TransferBytes", iTransfer);
        cJSON_AddFloatToObject(j, "Bandwidth", fBandwidth);
        cJSON_AddFloatToObject(j, "Jitter", fJitter);
        cJSON_AddIntToObject(j, "LostPackets", iPacketLost);
        cJSON_AddIntToObject(j, "TotalPackets", iPacketTotal);
        cJSON_AddFloatToObject(j, "PacketLoss", fLoss);
    }
    
    return j;
}

void UdpReport::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "BeginTime")) != NULL)
        fBeginTime = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "EndTime")) != NULL)
        fEndTime = pj->valuefloat;
    
    if ((pj = cJSON_GetObjectItem(json, "Interval")) != NULL)
        fInterval = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "TransferBytes")) != NULL)
        iTransfer = pj->valueint;
        
    if ((pj = cJSON_GetObjectItem(json, "Bandwidth")) != NULL)
        fBandwidth = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "Jitter")) != NULL)
        fJitter = pj->valuefloat;
        
    if ((pj = cJSON_GetObjectItem(json, "LostPackets")) != NULL)
        iPacketLost = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "TotalPackets")) != NULL)
        iPacketTotal = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "PacketLoss")) != NULL)
        fLoss = pj->valuefloat;
}

/******************************************************************************/
/*
 class Report
 */
/******************************************************************************/

cJSON * Report::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else{
        cJSON_AddIntToObject(j, "Protocol", iProto);
        cJSON_AddIntToObject(j, "Role", iRole);
        cJSON_AddStringToObject(j, "SenderIP", sSenderIP);
        cJSON_AddIntToObject(j, "SenderPort", iSenderPort);
        cJSON_AddStringToObject(j, "RecverIP", sRecverIP);
        cJSON_AddIntToObject(j, "RecverPort", iRecverPort);
        
        cJSON *json;    
        switch (iProto) {
            case (1):
                json = pTcpReport->GenToJson();
                cJSON_AddItemToObject(j, "TCPReport", json);
                break;
            case (2):
                json = pUdpReport->GenToJson();
                cJSON_AddItemToObject(j, "UDPReport", json);
                break;
        }
    }
        
    return j;
}

void Report::ParseFromJson(cJSON *json) {
    cJSON *pj;
    
    if ((pj = cJSON_GetObjectItem(json, "Role")) != NULL)
        iRole = pj->valueint;
        
    if ((pj = cJSON_GetObjectItem(json, "Protocol")) != NULL)
        iProto = pj->valueint;
    
    if ((pj = cJSON_GetObjectItem(json, "SenderIP")) != NULL)
        sSenderIP = strdup(pj->valuestring);

    if ((pj = cJSON_GetObjectItem(json, "SenderPort")) != NULL)
        iSenderPort = pj->valueint;

    if ((pj = cJSON_GetObjectItem(json, "RecverIP")) != NULL)
        sRecverIP = strdup(pj->valuestring);

    if ((pj = cJSON_GetObjectItem(json, "RecverPort")) != NULL)
        iRecverPort = pj->valueint;

    switch(iProto) {
        case (1):
            if ((pj = cJSON_GetObjectItem(json, "TCPReport")) != NULL) {
                pTcpReport = new TcpReport();
                pTcpReport->ParseFromJson(pj);
            }
            break;
        case (2):
            if ((pj = cJSON_GetObjectItem(json, "UdpReport")) != NULL) {
                pUdpReport = new UdpReport();
                pUdpReport->ParseFromJson(pj);
            }
            break;
    }
}

/******************************************************************************/
/*
 class Message
 */
/******************************************************************************/
cJSON * Message::GenToJson() {
    
    cJSON *j = cJSON_CreateObject();
    if( j == NULL )
        std::cout << "Memory Error: Cannot create JSON object." << std::endl;
    else {
        cJSON_AddStringToObject(j, "FromIP", sFromIP);
        cJSON_AddIntToObject(j, "FromPort", iFromPort);
        cJSON_AddStringToObject(j, "ToIP", sToIP);
        cJSON_AddIntToObject(j, "ToPort", iToPort);
        cJSON_AddIntToObject(j, "MessageType", iMessageType);
        
        cJSON *json;
        switch(iMessageType) {
            case (1):
                json = pRequest->GenToJson();
                cJSON_AddItemToObject(j, "Request", json);
                break;
            case (2):
                json = pReply->GenToJson();
                cJSON_AddItemToObject(j, "Reply", json);
                break;
            case (3):
                json = pReport->GenToJson();
                cJSON_AddItemToObject(j, "Report", json);
                break;
        }
    }
        
    return j;    
}
    
void Message::ParseFromJson(cJSON *json) {
    cJSON *pj;
        
    if ((pj = cJSON_GetObjectItem(json, "FromIP")) != NULL)
        sFromIP = strdup(pj->valuestring);
            
    if ((pj = cJSON_GetObjectItem(json, "FromPort")) != NULL)
        iFromPort = pj->valueint;
         
    if ((pj = cJSON_GetObjectItem(json, "ToIP")) != NULL )
        sToIP = strdup(pj->valuestring);
            
    if ((pj = cJSON_GetObjectItem(json, "ToPort")) != NULL)
        iToPort = pj->valueint;
            
    if ((pj = cJSON_GetObjectItem(json, "MessageType")) != NULL)
        iMessageType = pj->valueint;
        
    switch(iMessageType) {
        case (1):
            if ((pj = cJSON_GetObjectItem(json, "Request")) != NULL) {
                pRequest = new Request();
                pRequest->ParseFromJson(pj);
            }
            break;
        case (2):
            if ((pj = cJSON_GetObjectItem(json, "Reply")) != NULL) {
                pReply = new Reply();
                pReply->ParseFromJson(pj);
            }
            break;
        case (3):
            if ((pj = cJSON_GetObjectItem(json, "Report")) != NULL) {
                pReport = new Report();
                pReport->ParseFromJson(pj);
            }
            break;
    }
}

/******************************************************************************/
/* End File: message.cpp                                                      */
/******************************************************************************/